/*
 * GameHexagon.fx
 *
 * Created on Sep 5, 2009, 1:08:27 PM
 */

package fxbattle.fxgui;

import javafx.scene.CustomNode;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.transform.Transform;
import javafx.scene.effect.SepiaTone;
import fxbattle.client.model.Direction;
import javafx.scene.Group;
import java.lang.IllegalArgumentException;
import javafx.scene.shape.Line;
import javafx.scene.shape.Circle;
import javafx.util.Sequences;
import java.lang.Math;
import java.util.HashMap;
import javafx.scene.effect.ColorAdjust;


/**
 * @author spina
 */

def sin60 = Math.sin(Math.toRadians(60));
def cos60 = Math.cos(Math.toRadians(60));
def baseStroke = 8;
def normalStroke = 2;
def size = 50.0;
def pad = 2;
public def arrowSize = size * sin60 * .8;

public function createTranslation(row: Integer, col: Integer): Transform {
    //println("Creating Translation for: {row}, {col} ");
    def x : Number = col * size * 1.5 + pad - (size/3);
    def y : Number = if(Math.abs(col mod 2) == 1)
                  then (2 * row * size * sin60 + pad + size * sin60) - size / 2
                  else (2 * row * size * sin60 + pad) - size / 2;
    Transform.translate(x, y)
}

public class GameHexagon extends CustomNode {

    public var activeDirections: Direction[] = []
                on replace { //println("activeDirections is {activeDirections} index of north is {Sequences.indexOf(activeDirections, Direction.NORTH)}");
                             for(dir in Direction.values()){
                                (flowArrowMap.get(dir) as FlowArrow).visible = Sequences.indexOf(activeDirections, dir) != -1
                             }
                           };//println("activeDirs: {activeDirections}")};
    def flowArrowMap = new HashMap();
    // This is a temporary color...
    public var armyColor = Color.CADETBLUE;
    public var playerColor = Color.PINK;
    public var armySize = 0.0 on replace {
        if(armySize > 1 or armySize < 0){
            throw new IllegalArgumentException("Elevation must be between 1 and 0 it was {elevationPercent}");
        }
    };
    var hexColor = Color {
                red: .54
                blue: .27
                green: .07
                };
    public var elevationPercent = 0.0 on replace {
        if(elevationPercent > 1 or elevationPercent < 0){
            throw new IllegalArgumentException("Elevation must be between 1 and 0 it was {elevationPercent}");
        }
    };
    public var isBase = false;

    def bg_hex = Hexagon{
        cache: true
        size: size
        color: bind hexColor;
        effect: SepiaTone {
                level: bind 1.0 - elevationPercent
            }

        public override function mousePressedOnDirection(dir: Direction): Void{
            mousePressedOnDir(dir);
        }
        override public function mouseEnteredTriangle(dir: Direction): Void{
            mouseEnteredDir(dir);
        }
        override public function mouseExitedTriangle(dir: Direction): Void{
            mouseExitedDir(dir);
        }
        public override function toString(): String{"Hexagon at {translateX}, {translateY}"}
    };
    
    var hexbounds: Node[];
    var flowArrows: Node[];
    def armyCircle = Circle {
            cache: true
            centerX: 0, centerY: 0
            radius: bind if(armySize == 0) size * .15 else armySize * size * sin60
            fill: bind armyColor
            public override function toString(): String{"Army Size Circle"}
        };
    def centerArmyCircle = Circle {
                cache: true
                centerX: 0, centerY: 0
                radius: .1 * size
                  fill: Color.WHITESMOKE
                  visible: bind armySize == 0
                  public override function toString(): String{"Center Army Circle"}
        };

    public override function create(): Node {
        for(dir in Direction.values()){
            insert Line {
                cache: true
                var lineWidth = bind if(isBase) baseStroke else normalStroke
                startX: bind if(isBase) (-size / 2) + 3 else (-size / 2) + 1
                startY: bind if(isBase) size * sin60 - 2 else size * sin60 - 1
                endX: bind if(isBase) (size / 2) - 3 else (size / 2) - 1
                endY: bind if(isBase) size * sin60 - 2 else size * sin60 - 1
                strokeWidth: bind lineWidth
                stroke: bind armyColor
                transforms: [Transform.rotate(dir.angle(), 0, 0)]
                public override function toString(): String{"Boundary Line for {dir}"}
            } into hexbounds;
            var arrow = FlowArrow {
                cache: true
                visible: false
                length : arrowSize
                strokeWidth: 4
                stroke: bind playerColor
                effect: ColorAdjust {
                        brightness: -.2
                    }
                transforms : [Transform.rotate(dir.angle() - 90, 0, 0)]
                public override function toString(): String{"Flow Arrow for {dir}"}
            };
            insert arrow into flowArrows;
            flowArrowMap.put(dir, arrow);
        }
        return Group {
            content: [bg_hex, hexbounds, armyCircle, centerArmyCircle, flowArrows]
            // Optimization - about doulbed my frame rate on a 10 by 10 (from 2.9 to 5 fps)
            // Also gave took us from 8fps to 13 fps (for mouse dragging with arrow enabled) on 5 by 5
            cache: true
            public override function toString(): String{
                "Renders One Whole Game Hex"
            }

        };
    }

    public function mousePressedOnDir(dir: Direction){}
    public function mouseEnteredDir(dir: Direction): Void{}
    public function mouseExitedDir(dir: Direction): Void{}

}
